package com.zjuh.taofood.biz.ao.impl;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import wint.help.biz.result.Result;
import wint.help.biz.result.ResultSupport;
import wint.help.biz.result.StringResultCode;
import wint.lang.WintException;
import wint.lang.utils.MapUtil;
import wint.mvc.form.fileupload.UploadFile;

import com.zjuh.taofood.biz.ao.TopicAO;
import com.zjuh.taofood.biz.bo.ItemConverter;
import com.zjuh.taofood.biz.dao.ActiveTopicItemDAO;
import com.zjuh.taofood.biz.dao.TopicDAO;
import com.zjuh.taofood.biz.dao.TopicItemDAO;
import com.zjuh.taofood.biz.dao.query.ActiveTopicItemQuery;
import com.zjuh.taofood.biz.dao.query.TopicItemQuery;
import com.zjuh.taofood.biz.dao.query.TopicQuery;
import com.zjuh.taofood.biz.domain.ActiveTopicItemDO;
import com.zjuh.taofood.biz.domain.TopicDO;
import com.zjuh.taofood.biz.domain.TopicItemDO;
import com.zjuh.taofood.biz.resultcodes.TopicResultCodes;

public class TopicAOImpl extends BaseAO implements TopicAO {

	private TopicDAO topicDAO;
	
	private ActiveTopicItemDAO activeTopicItemDAO;
	
	private TopicItemDAO topicItemDAO;
	
	private File imageBasePath;
	
	private String topicImageName = "topicImage";
	
	@Override
	public Result removeItemFromTopic(long id) {
		Result result = new ResultSupport(false);
		try {

			ActiveTopicItemDO activeTopicItemDO = activeTopicItemDAO.queryById(id);
			if (activeTopicItemDO != null) {
				activeTopicItemDAO.delete(id);
				computeTopicItemCount(activeTopicItemDO.getTopicId());
			}
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("removeItemFromTopic error", e);
		}
		return result;
	}
	
	private void computeTopicItemCount(long topicId) {
		int itemCount = activeTopicItemDAO.queryCountByTopicId(topicId);
		topicDAO.updateItemCount(topicId, itemCount);
	}

	@Override
	public Result addItemsToTopic(long topicId, List<Long> itemIds) {
		Result result = new ResultSupport(false);
		try {
			boolean success = true;
			for (Long itemId : itemIds) {
				success = addSingleItemToTopic(topicId, itemId, result);
				if (!success) {
					break;
				}
			}
			computeTopicItemCount(topicId);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("addItemsToTopic error", e);
		}
		return result;
	}
	
	private boolean addSingleItemToTopic(long topicId, long itemId, Result result) {
		TopicItemDO topicItemDO = topicItemDAO.queryByItemId(itemId);
		if (topicItemDO == null) {
			result.setResultCode(new StringResultCode("item not exist!"));
			return false;
		}
		TopicDO topicDO = topicDAO.queryById(topicId);
		if (topicDO == null) {
			result.setResultCode(new StringResultCode("topic not exist!"));
			return false;
		}
		ActiveTopicItemDO inDb =  activeTopicItemDAO.queryByItemIdAndTopicId(itemId, topicId);
		if (inDb != null) {
			// 已经添加
		} else {
			ActiveTopicItemDO activeTopicItemDO = ItemConverter.toActiveTopicItemDO(topicItemDO, topicId);
			activeTopicItemDAO.create(activeTopicItemDO);
		}
		return true;
	}
	

	@Override
	public Result addItemToTopic(long topicId, long itemId) {
		Result result = new ResultSupport(false);
		try {
			boolean success = addSingleItemToTopic(topicId, itemId, result);
			computeTopicItemCount(topicId);
			result.setSuccess(success);
		} catch (Exception e) {
			log.error("addItemToTopic error", e);
		}
		return result;
	}

	@Override
	public Result searchTopicItems(TopicItemQuery topicItemQuery) {
		Result result = new ResultSupport(false);
		try {
			List<TopicItemDO> topicItems = topicItemDAO.searchTopicItems(topicItemQuery);
			result.getModels().put("topicItems", topicItems);
			result.getModels().put("topicItemQuery", topicItemQuery);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("searchTopicItems error", e);
		}
		return result;
	}

	public Result viewTopicDetail(long topicId, int itemsPage) {
		Result result = new ResultSupport(false);
		try {
			TopicDO topic = topicDAO.queryById(topicId);
			if (topic == null) {
				result.setResultCode(TopicResultCodes.TOPIC_NOT_EXIST);
				return result;
			}

			ActiveTopicItemQuery activeTopicItemQuery = new ActiveTopicItemQuery();
			activeTopicItemQuery.setPageNo(itemsPage);
			activeTopicItemQuery.setTopicId(topicId);
			activeTopicItemQuery.setPageSize(60);
			List<ActiveTopicItemDO> activeTopicItems = activeTopicItemDAO.queryByTopicId(activeTopicItemQuery);

			TopicQuery topicQuery = new TopicQuery();
			topicQuery.setPageNo(1);
			topicQuery.setPageSize(60);
			List<TopicDO> topics = topicDAO.queryForPageOrderByAttention(topicQuery);

			result.getModels().put("topic", topic);
			result.getModels().put("topics", topics);
			result.getModels().put("activeTopicItemQuery", activeTopicItemQuery);
			result.getModels().put("activeTopicItems", activeTopicItems);

			topicDAO.incrAttention(topicId);

			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewTopicDetail error", e);
		}
		return result;
	}
	
	@Override
	public Result viewTopicList(TopicQuery topicQuery) {
		Result result = new ResultSupport(false);
		try {
			List<TopicDO> topics = topicDAO.queryForPageOrderByAttention(topicQuery);
			result.getModels().put("topics", topics);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewTopicList error", e);
		}
		return result;
	}
	
	public Result viewIndex() {
		Result result = new ResultSupport(false);
		try {
			TopicQuery topicQuery = new TopicQuery();
			topicQuery.setPageNo(1);
			topicQuery.setPageSize(60);
			List<TopicDO> topics = topicDAO.queryForPageOrderByAttention(topicQuery);
			result.getModels().put("topics", topics);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewIndex error", e);
		}
		return result;
	}
	
	public Result viewTopicListForAdmin(TopicQuery topicQuery) {
		Result result = new ResultSupport(false);
		try {
			List<TopicDO> topics = topicDAO.queryForPage(topicQuery);
			result.getModels().put("topics", topics);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewTopicListForAdmin error", e);
		}
		return result;
	}

	@Override
	public Result modifyTopicImage(long topicId, Map<String, UploadFile> uploadFiles) {
		Result result = new ResultSupport(false);
		try {
			TopicDO topic = topicDAO.queryById(topicId);
			if (topic == null) {
				result.setResultCode(TopicResultCodes.TOPIC_NOT_EXIST);
				return result;
			}
			if (!MapUtil.isEmpty(uploadFiles)) {
				UploadFile uploadFile = uploadFiles.get(topicImageName);
				if (uploadFile != null) {
					String fileName = genFileName();
					File file = new File(this.imageBasePath, fileName);
					uploadFile.writeTo(file);
					topic.setImageUrl(fileName);
				}
			}
			topicDAO.update(topic);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("modifyTopicImage error", e);
		}
		return result;
	}

	public Result createTopic(TopicDO topic, Map<String, UploadFile> uploadFiles) {
		Result result = new ResultSupport(false);
		try {
			if (!MapUtil.isEmpty(uploadFiles)) {
				UploadFile uploadFile = uploadFiles.get(topicImageName);
				if (uploadFile != null) {
					String fileName = genFileName();
					File file = new File(this.imageBasePath, fileName);
					uploadFile.writeTo(file);
					topic.setImageUrl(fileName);
				}
			}
			long id = topicDAO.create(topic);
			result.getModels().put("id", id);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("createTopic error", e);
		}
		return result;
	}
	
	private String genFileName() {
		return UUID.randomUUID().toString();
	}
	
	@Override
	public Result viewTopicDetailForAdmin(long id, int page) {
		Result result = new ResultSupport(false);
		try {
			TopicDO topic = topicDAO.queryById(id);
			if (topic == null) {
				result.setResultCode(TopicResultCodes.TOPIC_NOT_EXIST);
				return result;
			}
			ActiveTopicItemQuery activeTopicItemQuery = new ActiveTopicItemQuery();
			activeTopicItemQuery.setPageNo(page);
			activeTopicItemQuery.setPageSize(50);
			activeTopicItemQuery.setTopicId(id);
			List<ActiveTopicItemDO> activeTopicItems = activeTopicItemDAO.queryByTopicId(activeTopicItemQuery);

			result.getModels().put("activeTopicItems", activeTopicItems);
			result.getModels().put("topic", topic);
			result.getModels().put("query", activeTopicItemQuery);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewTopicDetailForAdmin error", e);
		}
		return result;
	}
	
	public Result deleteTopicDetailForAdmin(long id) {
		Result result = new ResultSupport(false);
		try {
			TopicDO topic = topicDAO.queryById(id);
			if (topic == null) {
				result.setResultCode(TopicResultCodes.TOPIC_NOT_EXIST);
				return result;
			}
			topicDAO.delete(id);
			this.activeTopicItemDAO.deleteByTopicId(id);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("deleteTopicDetailForAdmin error", e);
		}
		return result;
	}

	@Override
	public Result viewTopicModifyForAdmin(long id) {
		Result result = new ResultSupport(false);
		try {
			TopicDO topic = topicDAO.queryById(id);
			if (topic == null) {
				result.setResultCode(TopicResultCodes.TOPIC_NOT_EXIST);
				return result;
			}
			result.getModels().put("topic", topic);
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("viewTopicModifyForAdmin error", e);
		}
		return result;
	}

	@Override
	public Result modifyTopicForAdmin(TopicDO topicInput) {
		Result result = new ResultSupport(false);
		try {
			TopicDO topic = topicDAO.queryById(topicInput.getId());
			if (topic == null) {
				result.setResultCode(TopicResultCodes.TOPIC_NOT_EXIST);
				return result;
			}
			topic.setDescription(topicInput.getDescription());
			topic.setTitle(topicInput.getTitle());
			topic.setSortSeq(topicInput.getSortSeq());

			topicDAO.update(topic);

			result.setSuccess(true);
		} catch (Exception e) {
			log.error("modifyTopicForAdmin error", e);
		}
		return result;
	}

	public void setTopicDAO(TopicDAO topicDAO) {
		this.topicDAO = topicDAO;
	}

	public void setActiveTopicItemDAO(ActiveTopicItemDAO activeTopicItemDAO) {
		this.activeTopicItemDAO = activeTopicItemDAO;
	}

	public void setTopicItemDAO(TopicItemDAO topicItemDAO) {
		this.topicItemDAO = topicItemDAO;
	}

	public void setImagePath(String imagePath) {
		this.imageBasePath = new File(imagePath);
		if (imageBasePath.exists() && !imageBasePath.isDirectory()) {
			throw new WintException(imagePath + " must be a directory!");
		}
		if (!imageBasePath.exists()) {
			imageBasePath.mkdirs();
		}
	}

}
